package com.enation.app.javashop.manager.api.account;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.dag.eagleshop.core.account.model.dto.base.IdsDTO;
import com.dag.eagleshop.core.account.model.dto.base.PageDTO;
import com.dag.eagleshop.core.account.model.dto.base.SortField;
import com.dag.eagleshop.core.account.model.dto.base.ViewPage;
import com.dag.eagleshop.core.account.model.dto.withdraw.*;
import com.dag.eagleshop.core.account.model.enums.WithdrawStatusEnum;
import com.dag.eagleshop.core.account.model.vo.WithdrawResult;
import com.dag.eagleshop.core.account.service.AccountManager;
import com.enation.app.javashop.core.excel.ExcelManager;
import com.enation.app.javashop.core.payment.service.WechatSmallchangeManager;
import com.enation.app.javashop.core.system.sendMessage.WechatSendMessage;
import com.enation.app.javashop.framework.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 提现控制器
 *
 * @author 孙建
 */
@Api(description = "提现接口模块")
@RestController
@RequestMapping("/account/withdraw")
public class WithdrawController {

    @Autowired
    private AccountManager accountManager;
    @Autowired
    private WechatSendMessage wechatSendMessage;
    @Autowired
    private WechatSmallchangeManager wechatSmallchangeManager;
    @Autowired
    private ExcelManager excelManager;

    protected final Log logger = LogFactory.getLog(this.getClass());

    @PostMapping("/queryWithdrawList")
    @ApiOperation(value = "查询提现记录")
    public ViewPage<WithdrawBillDTO> queryWithdrawList(@RequestBody PageDTO<QueryWithdrawBillDTO> pageDTO) {
        pageDTO.setOrderBys(new SortField[]{new SortField(false, "create_time")});
        return accountManager.queryWithdrawList(pageDTO);
    }

    @PostMapping(value = "/auditing")
    @ApiOperation("提现审核")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "withdraw_bill_ids", value = "提现记录id", required = true, paramType = "query", dataType = "int", allowMultiple = false),
            @ApiImplicitParam(name = "remark", value = "备注", required = false, paramType = "query", dataType = "String", allowMultiple = false),
            @ApiImplicitParam(name = "status", value = "申请结果", required = true, paramType = "query", dataType = "Integer", allowMultiple = false),
    })
    public WithdrawResult auditing(@ApiIgnore String withdrawBillIds, String remark, @ApiIgnore Integer status) {
        String[] withdrawBillIdss = withdrawBillIds.split(",");
        //保存转账发生错误的单号和错误原因
        Map<String, String> map = new HashMap<>();
        //默认会发小程序推送
        Boolean sendStatus = true;
        for (String withdrawBillId : withdrawBillIdss) {
            AuditingDTO auditingDTO = new AuditingDTO();
            try {
                auditingDTO.setWithdrawBillId(withdrawBillId);
                auditingDTO.setInspectRemark(remark);
                auditingDTO.setStatus(status);
                auditingDTO.setOperatorId("1");
                auditingDTO.setOperatorName("平台");
                sendStatus = accountManager.auditing(auditingDTO);
            } catch (Exception e) {
                //不发小程序推送
                sendStatus = false;
                map.put(withdrawBillId, e.getMessage());
                logger.error("提现审核异常：", e);
            }
            // 审核功能没有捕获到异常且审核拒绝时发推送
            if (sendStatus && WithdrawStatusEnum.REFUSE.getIndex() == status) {
                wechatSendMessage.sendAuditingMessage(auditingDTO);
            }
        }
        //如果有审核失败的申请单返回失败单号及失败原因
        if (map.size() > 0) {
            List<WithdrawBill> withdrawBillList = accountManager.queryListByIds(IdsDTO.by(new ArrayList<>(map.keySet())));
            for (int i = 0; i < withdrawBillList.size(); i++) {
                WithdrawBill withdrawBill = JSON.parseObject(JSON.toJSON(withdrawBillList.get(i)).toString(), new TypeReference<WithdrawBill>() {
                });
                withdrawBill.setTransferRemark(map.get(withdrawBill.getId()));
                logger.debug("失败单号的失败原因:"+withdrawBill.toString());
                withdrawBillList.set(i,withdrawBill);
            }
            return new WithdrawResult(601, withdrawBillList);
        }
        return new WithdrawResult(200, "审核完成");
    }

    @ApiOperation("标记为已转账")
    @PostMapping(value = "/markTransfer")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "withdraw_bill_ids", value = "提现记录id", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "transfer_remark", value = "备注", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "status", value = "打款状态", required = false, paramType = "query", dataType = "Integer"),
    })
    public WithdrawResult markTransfer(@ApiIgnore String withdrawBillIds, String transferRemark,Integer status) {
        String[] withdrawBillIdss = withdrawBillIds.split(",");

        //保存转账发生错误的单号和错误原因
        Map<String, String> map = new HashMap<>();
        int num = 0;
        for (String withdrawBillId : withdrawBillIdss) {
            num++;
            // 打款
            MarkTransferredDTO markTransferredDTO = new MarkTransferredDTO();
            try {
                markTransferredDTO.setWithdrawBillId(withdrawBillId);
                markTransferredDTO.setTransferRemark(transferRemark);
                markTransferredDTO.setOperatorId("1");
                markTransferredDTO.setOperatorName("平台");
                markTransferredDTO.setStatus(status);
                logger.info("调用转账方法markTransfer：" + num + JSON.toJSON(markTransferredDTO).toString());
                markTransferredDTO = accountManager.markTransfer(markTransferredDTO);

                //如果微信转账参数校验出错或转账失败，会弹窗提示管理员
                String realFailReason=markTransferredDTO.getRealFailReason();
                if(!StringUtil.isEmpty(realFailReason)){
                    map.put(withdrawBillId, realFailReason);
                }
            } catch (Exception e) {
                //不发小程序推送,只提示
                map.put(withdrawBillId, e.getMessage());
                this.logger.error("标记为已转账 Exception：", e);
            }
        }

        //如果有打款失败的返回失败单号及失败原因
        if (map.size() > 0) {
            List<WithdrawBill> withdrawBillList = accountManager.queryListByIds(IdsDTO.by(new ArrayList<>(map.keySet())));
            for (int i = 0; i < withdrawBillList.size(); i++) {
                WithdrawBill withdrawBill = JSON.parseObject(JSON.toJSON(withdrawBillList.get(i)).toString(), new TypeReference<WithdrawBill>() {
                });
                withdrawBill.setTransferRemark(map.get(withdrawBill.getId()));
                logger.debug("失败单号的失败原因:"+withdrawBill.toString());
                withdrawBillList.set(i,withdrawBill);
            }
            return new WithdrawResult(601, withdrawBillList);
        }
        return new WithdrawResult(200, "支付中");
    }

    @ApiOperation("查询转账是否成功")
    @GetMapping(value = "/gettransferinfo")
    public Map<String,String> gettransferinfo(@RequestParam(value = "transferNo") String transferNo) {
        if (StringUtil.notEmpty(transferNo)) {
            return wechatSmallchangeManager.gettransferinfo(transferNo);
        } else {
            return null;
        }

    }

    @PostMapping("/withdrawBillExport")
    @ApiOperation(value = "导出提现记录")
    public void withdrawBillExport(@RequestBody PageDTO<QueryWithdrawBillDTO> pageDTO) {
        pageDTO.setOrderBys(new SortField[]{new SortField(false, "create_time")});
        pageDTO.setPageNum(1);
        pageDTO.setPageSize(1000);
        excelManager.withdrawBillExport(pageDTO);
    }
}
